home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: Music.cpp
- //
- // Desc:
- //
- // Copyright (c) 1995-2001 Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
- #define STRICT
- #include <windows.h>
- #include <tchar.h>
- #include <oleauto.h>
- #include <stdio.h>
- #include "DXUtil.h"
- #include "music.h"
-
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- BoidMusic::BoidMusic()
- {
- m_dwBeatsSinceLastMotif = 0;
- m_pSegment = NULL;
- m_pPort = NULL;
- m_pDMusic = NULL;
- m_fCollapsed = FALSE;
- m_dwIndex = 0;
- m_pBand = NULL;
- m_pStyle = NULL;
- m_pChordMap = NULL;
- long x;
- for (x = 0; x < 6; x++)
- {
- m_pTemplateSegments[x] = NULL;
- m_pPrimarySegments[x] = NULL;
- m_pMotifSegments[x] = NULL;
- }
- m_pPrimarySegments[1] = NULL;
- m_pTransitionSegment = NULL;
- m_pComposer = NULL;
- m_pLoader = NULL;
- m_pPerformance = NULL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- BoidMusic::~BoidMusic()
- {
- long x;
- if (m_pSegment)
- {
- m_pSegment->Release();
- }
- if (m_pBand)
- {
- if(m_pPerformance)
- {
- m_pBand->Unload(m_pPerformance);
- }
- m_pBand->Release();
- }
- if (m_pGraph)
- {
- m_pGraph->Release();
- }
- if (m_pPort)
- {
- m_pPort->Release();
- }
- if (m_pDMusic)
- {
- m_pDMusic->Release();
- }
- for (x = 0; x< 6; x++)
- {
- if (m_pTemplateSegments[x])
- {
- m_pTemplateSegments[x]->Release();
- }
- if (m_pPrimarySegments[x])
- {
- m_pPrimarySegments[x]->Release();
- }
- if (m_pMotifSegments[x])
- {
- m_pMotifSegments[x]->Release();
- }
- }
- if (m_pStyle)
- {
- m_pStyle->Release();
- }
- if (m_pChordMap)
- {
- m_pChordMap->Release();
- }
- if (m_pTransitionSegment)
- {
- m_pTransitionSegment->Release();
- }
- if (m_pComposer)
- {
- m_pComposer->Release();
- }
- if (m_pLoader)
- {
- m_pLoader->Release();
- }
- if (m_pPerformance)
- {
- m_pPerformance->Release();
- }
- if( m_hNotify )
- {
- CloseHandle( m_hNotify );
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::LoadStyle()
- {
- if (m_pStyle) m_pStyle->Release();
-
- DMUS_OBJECTDESC ObjectDescript;
- ObjectDescript.guidClass = CLSID_DirectMusicStyle;
- wcscpy(ObjectDescript.wszFileName, L"Boids2.sty");
- ObjectDescript.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME ;
- ObjectDescript.dwSize = sizeof(DMUS_OBJECTDESC);
- if (SUCCEEDED(m_pLoader->GetObject(&ObjectDescript, IID_IDirectMusicStyle, (void**)&m_pStyle)))
- {
- BSTR bstr = SysAllocString(L"Default");
- m_pStyle->GetBand(bstr, &m_pBand) ;
- SysFreeString(bstr);
-
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: This loads a precomposed segment.
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::LoadSegment()
- {
- if (m_pSegment) m_pSegment->Release();
-
- DMUS_OBJECTDESC ObjectDescript;
- ObjectDescript.guidClass = CLSID_DirectMusicSegment;
- wcscpy(ObjectDescript.wszFileName, L"BoidsD.sgt");
- ObjectDescript.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME ;
- ObjectDescript.dwSize = sizeof(DMUS_OBJECTDESC);
- if (SUCCEEDED(m_pLoader->GetObject(&ObjectDescript, IID_IDirectMusicSegment, (void**)&m_pSegment)))
- {
-
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Load the dls set that the band needs, but just leave it in the cache.
- // Then, it will be referenced and loaded by the bands in the styles and
- // segments.
- //-----------------------------------------------------------------------------
- HRESULT BoidMusic::LoadDLS()
- {
- DMUS_OBJECTDESC dmod;
- dmod.dwSize = sizeof(DMUS_OBJECTDESC);
- dmod.guidClass = CLSID_DirectMusicCollection;
- dmod.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME ;
- wcscpy(dmod.wszFileName, L"Boids.dls");
-
- IDirectMusicCollection* pCollect = NULL;
- if( FAILED( m_pLoader->GetObject( &dmod, IID_IDirectMusicCollection,
- (VOID**)&pCollect ) ) )
- return E_FAIL;
-
- pCollect->Release();
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Load the Boids chord map.
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::LoadChordMap()
- {
- if (m_pChordMap) m_pChordMap->Release();
-
- DMUS_OBJECTDESC ObjectDescript;
- ObjectDescript.guidClass = CLSID_DirectMusicChordMap;
- wcscpy(ObjectDescript.wszFileName, L"Boids.cdm");
- ObjectDescript.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
- ObjectDescript.dwSize = sizeof(DMUS_OBJECTDESC);
- if (SUCCEEDED(m_pLoader->GetObject(&ObjectDescript, IID_IDirectMusicChordMap, (void**)&m_pChordMap)))
- {
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Load a template and place it in the m_pTemplateSegments[] array.
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::LoadTemplate(DWORD dwIndex, WCHAR * pwzName)
- {
- if (m_pTemplateSegments[dwIndex]) m_pTemplateSegments[dwIndex]->Release();
-
- HRESULT hr;
- DMUS_OBJECTDESC ObjectDescript;
-
- ObjectDescript.guidClass = CLSID_DirectMusicSegment;
- wcscpy(ObjectDescript.wszFileName, pwzName);
- ObjectDescript.dwValidData = DMUS_OBJ_CLASS | DMUS_OBJ_FILENAME;
- ObjectDescript.dwSize = sizeof(DMUS_OBJECTDESC);
- if (SUCCEEDED( hr = m_pLoader->GetObject(&ObjectDescript, IID_IDirectMusicSegment, (void**)&m_pTemplateSegments[dwIndex])))
- {
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Use the composer to compose a style segment from a previously loaded
- // template segment, the boids chord map and style. Place the
- // segment in the m_pPrimarySegments[] array.
- //-----------------------------------------------------------------------------
- void BoidMusic::ComposeSegment(DWORD dwIndex)
- {
-
- if (m_pComposer && m_pStyle && m_pChordMap && m_pTemplateSegments[dwIndex])
- {
- if (m_pPrimarySegments[dwIndex])
- {
- m_pPrimarySegments[dwIndex]->Release();
- m_pPrimarySegments[dwIndex] = NULL;
- }
- m_pComposer->ComposeSegmentFromTemplate(
- m_pStyle,
- m_pTemplateSegments[dwIndex],
- 1,
- m_pChordMap,
- &m_pPrimarySegments[dwIndex]);
- if (m_pPrimarySegments[dwIndex])
- {
- m_pPrimarySegments[dwIndex]->SetRepeats(100);
-
- }
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Pull the named motif segment from the boids style.
- // Note that we currently use the OLE BSTR string approach.
- // This will probably change in the next beta.
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::GetMotif(DWORD dwIndex, WCHAR * pszName)
- {
- if (m_pStyle)
- {
- if (SUCCEEDED(m_pStyle->GetMotif(pszName, &m_pMotifSegments[dwIndex])))
- {
- return TRUE;
- }
- }
-
- return FALSE;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Check for a notify event. Since we are only waiting for
- // notification of beats, we increment out beat counter. The beat counter
- // is used by the boids app to manage the number of motifs allowed at any
- // point in time. This keeps things from getting too overcrowded.
- // Alternatively, the notifications could be used to synchronize graphic
- // events.
- //-----------------------------------------------------------------------------
- void BoidMusic::HandleNotifies()
- {
- DMUS_NOTIFICATION_PMSG* pMsg;
- if( m_hNotify && m_pPerformance)
- {
- WaitForSingleObject(m_hNotify, 2);
- while( S_OK == m_pPerformance->GetNotificationPMsg(&pMsg))
- {
- m_pPerformance->FreePMsg((DMUS_PMSG*)pMsg);
- m_dwBeatsSinceLastMotif++;
- }
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: This is called by the app, once it gets its main window up.
- // Activate the synth and start the music playing.
- //-----------------------------------------------------------------------------
- void BoidMusic::StartMusic()
- {
- if (m_pDMusic)
- {
- m_pDMusic->Activate(TRUE);
- }
- if (m_pPrimarySegments[0])
- {
- m_pPerformance->PlaySegment(
- m_pPrimarySegments[0], 0, 0, NULL);
- m_dwIndex = 0;
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: This is called from the graphics loop. As we get closer to the center
- // of the flock of birds, increase the number of echoes for the echo tool,
- // and also increase the duration scalings (makes the note durations
- // longer.)
- //-----------------------------------------------------------------------------
- void BoidMusic::SetDistance(double fDistance)
- {
- double fTemp = fDistance - 10.0;
- fTemp = 70.0 - fTemp;
- if (fTemp < 0.0) fTemp = 0.0;
- m_Tool.m_dwEcho = (DWORD)(fTemp / 15.0);
- m_Tool.m_dwStartRatio = (DWORD)(75 + fTemp);
- m_Tool.m_dwRatio = m_Tool.m_dwStartRatio;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Whenever the flock is about to hit a sphere, this is called. It
- // chooses the next segment to go to and plays the planet motif leading
- // into the next segment. Notice how it takes the start time of the
- // planet motif, adds one, and uses that to start the segment, but on a
- // beat boundary. This tricks the segment to start one beat later than
- // the motif, creating a smooth musical transition.
- //-----------------------------------------------------------------------------
- void BoidMusic::Transition()
- {
- if (!m_fCollapsed && (m_dwBeatsSinceLastMotif > 2))
- {
- static DWORD dwChoice[8] = { 0, 2, 1, 3, 0, 4, 1, 5 };
- m_dwIndex++;
- if (m_dwIndex > 8) m_dwIndex = 2;
- if (m_dwIndex > 0)
- {
- if (m_pMotifSegments[0] && m_pPrimarySegments[dwChoice[m_dwIndex-1]])
- {
- IDirectMusicSegmentState *pState = NULL;
- m_pPerformance->PlaySegment(
- m_pMotifSegments[0], (DMUS_SEGF_SECONDARY | DMUS_SEGF_BEAT ), 0, &pState);
- if (pState)
- {
- MUSIC_TIME mtTime;
- pState->GetStartTime(&mtTime);
- pState->Release();
- mtTime++;
- m_pPerformance->PlaySegment(
- m_pPrimarySegments[dwChoice[m_dwIndex-1]], DMUS_SEGF_BEAT , mtTime, NULL);
- }
- }
- }
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: When the migration force is turned off, the birds start to migrate
- // away. So, this starts the migration theme. Note that it plays once,
- // and then one of the regular segments is queued to pick up after it.
- //-----------------------------------------------------------------------------
- void BoidMusic::Migrate()
- {
- if (m_pSegment)
- {
- m_pPerformance->PlaySegment(
- m_pSegment, DMUS_SEGF_BEAT , 0, NULL);
- }
- if (m_pPrimarySegments[2])
- {
- m_pPerformance->PlaySegment(
- m_pPrimarySegments[2], DMUS_SEGF_QUEUE , 0, NULL);
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: When the 's' key or space bar is hit, the birds collapse together. Set
- // the collapsed flag indicating the new state. Trigger two motifs to
- // play. The first simply plays the collapse motif. The second plays a
- // cycling motif until the user lifts up, calling the Expand() function.
- //-----------------------------------------------------------------------------
- void BoidMusic::Collapse()
- {
- m_fCollapsed = TRUE;
- if (m_dwBeatsSinceLastMotif)
- {
- if (m_pMotifSegments[5])
- {
- m_pPerformance->PlaySegment(
- m_pMotifSegments[5], (DMUS_SEGF_SECONDARY | DMUS_SEGF_GRID), 0, NULL);
- }
- if (m_pMotifSegments[3])
- {
- m_pMotifSegments[3]->SetRepeats(20);
- m_pPerformance->PlaySegment(
- m_pMotifSegments[3], (DMUS_SEGF_SECONDARY | DMUS_SEGF_MEASURE), 0, NULL);
- }
- m_dwBeatsSinceLastMotif = 0;
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: When the user releases the 's' key or space bar, the birds can move
- // apart again. Notice that the repeating motif is turned off by calling
- // stop on it.
- //-----------------------------------------------------------------------------
- void BoidMusic::Expand()
- {
- m_fCollapsed = FALSE;
- if (m_dwBeatsSinceLastMotif)
- {
- if (m_pMotifSegments[4])
- {
- m_pPerformance->PlaySegment(
- m_pMotifSegments[4], (DMUS_SEGF_SECONDARY | DMUS_SEGF_GRID), 0, NULL);
- }
- m_dwBeatsSinceLastMotif = 0;
- }
- if (m_pMotifSegments[3])
- {
- m_pPerformance->Stop(m_pMotifSegments[3], NULL, 0, 0);
- }
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc: Close down all the music stuff.
- //-----------------------------------------------------------------------------
- void BoidMusic::EndMusic()
- {
- m_Tool.m_pPerformance = NULL;
- if (m_pPerformance)
- {
- m_pPerformance->Stop( NULL, NULL, 0, 0);
- }
- if (m_pSegment)
- {
- m_pSegment->Release();
- m_pSegment = NULL;
- }
- if (m_pBand)
- {
- if(m_pPerformance)
- {
- m_pBand->Unload(m_pPerformance);
- }
- m_pBand->Release();
- m_pBand = NULL;
- }
- if (m_pPort)
- {
- m_pPort->Release();
- m_pPort = NULL;
- }
- if (m_pDMusic)
- {
- m_pDMusic->Release();
- m_pDMusic = NULL;
- }
- if (m_pGraph)
- {
- m_pGraph->Release();
- m_pGraph = NULL;
- }
- long x;
- for (x = 0; x< 6; x++)
- {
- if (m_pTemplateSegments[x])
- {
- m_pTemplateSegments[x]->Release();
- m_pTemplateSegments[x] = NULL;
- }
- if (m_pPrimarySegments[x])
- {
- m_pPrimarySegments[x]->Release();
- m_pPrimarySegments[x] = NULL;
- }
- if (m_pMotifSegments[x])
- {
- m_pMotifSegments[x]->Release();
- m_pMotifSegments[x] = NULL;
- }
- }
- if (m_pStyle)
- {
- m_pStyle->Release();
- m_pStyle = NULL;
- }
- if (m_pChordMap)
- {
- m_pChordMap->Release();
- m_pChordMap = NULL;
- }
- if (m_pTransitionSegment)
- {
- m_pTransitionSegment->Release();
- m_pTransitionSegment = NULL;
- }
- if (m_pComposer)
- {
- m_pComposer->Release();
- m_pComposer = NULL;
- }
- if (m_pLoader)
- {
- m_pLoader->Release();
- m_pLoader = NULL;
- }
- if (m_pPerformance)
- {
- m_pPerformance->Stop( NULL, NULL, 0, 0);
- m_pPerformance->CloseDown();
- m_pPerformance->Release();
- m_pPerformance = NULL;
- }
- CoUninitialize();
- }
-
- static char szDirectMusicMedia[] = "Media";
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- BOOL BoidMusic::GetSearchPath(WCHAR wszPath[MAX_PATH])
- {
- const TCHAR* szDir = DXUtil_GetDXSDKMediaPath();
- mbstowcs(wszPath, szDir, MAX_PATH);
-
- return TRUE;
- }
-
-
-
-
- // Tool implementation follows. Pretty much all the meat is in the
- // ProcessEvent() method.
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- CTool::CTool()
- {
- m_dwRatio = 100;
- m_dwStartRatio = 100;
- m_dwEcho = 1;
- m_cRef = 0;
- m_dwDelay = 96;
- m_pPerformance = NULL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- CTool::~CTool()
- {
- }
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- STDMETHODIMP CTool::QueryInterface( const IID &iid, void **ppv)
- {
- if (iid == IID_IDirectMusicTool)
- {
- *ppv = static_cast<IDirectMusicTool*>(this);
- } else
- {
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- reinterpret_cast<IUnknown*>(this)->AddRef();
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- STDMETHODIMP_(ULONG) CTool::AddRef()
- {
- return InterlockedIncrement(&m_cRef);
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- STDMETHODIMP_(ULONG) CTool::Release()
- {
- if (!InterlockedDecrement(&m_cRef))
- {
- return 0;
- }
-
- return m_cRef;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::ProcessPMsg( IDirectMusicPerformance* pPerf,
- DMUS_PMSG* pMsg )
- {
- HRESULT hr = S_OK;
- if (pMsg->pGraph)
- {
- if (SUCCEEDED(pMsg->pGraph->StampPMsg(pMsg)))
- {
- hr = DMUS_S_REQUEUE;
- }
- }
- switch( pMsg->dwType )
- {
- case DMUS_PMSGT_NOTE:
- {
- /* If we receive a note, first adjust the duration
- by m_dwRatio.
- */
- DMUS_NOTE_PMSG *pNote = (DMUS_NOTE_PMSG *) pMsg;
- if (m_dwRatio < 1) m_dwRatio = 1;
- if (m_dwRatio > 400) m_dwRatio = 400;
- pNote->mtDuration = MulDiv(pNote->mtDuration,m_dwRatio,100);
- /* Then, if it is on the PChannel of the melody,
- set it to echo the number of times established
- by m_dwEcho. Note that the echo algorithm is
- quite simple but powerful: copy the event and play
- it on an adjacent PChannel. By playing it on a different
- PChannel, we take care of overlapping notes and
- we can have it panned differently.
- */
- if (m_dwEcho && (pNote->dwPChannel == 7))
- {
- if (pPerf)
- {
- DWORD dwX;
- if (m_dwEcho > 3) m_dwEcho = 3;
- for (dwX = 0; dwX < m_dwEcho; dwX++)
- {
- DMUS_NOTE_PMSG * pEcho;
- if (SUCCEEDED(pPerf->AllocPMsg( sizeof(DMUS_NOTE_PMSG),
- (DMUS_PMSG**) &pEcho)))
- {
- static DWORD dwChannels[3] = { 6, 15, 0 };
- memcpy( pEcho, pNote, sizeof(DMUS_NOTE_PMSG) );
- pEcho->dwPChannel = dwChannels[dwX];
- pEcho->mtTime = pNote->mtTime + (m_dwDelay * (dwX + 1));
- pEcho->dwFlags = DMUS_PMSGF_MUSICTIME;
- if (pEcho->pGraph) pEcho->pGraph->AddRef();
- if (pEcho->pTool) pEcho->pTool->AddRef();
- pPerf->SendPMsg( (DMUS_PMSG*)pEcho) ;
- }
- }
- }
- }
- }
- break;
- case DMUS_PMSGT_CURVE:
- break;
- case DMUS_PMSGT_SYSEX:
- break;
- case DMUS_PMSGT_MIDI:
- /* Also, if we receive program changes, volumes, or pans on the
- PChannel of the melody, set up the echos to use the same patch,
- a diminishing volume, and assign the pans appropriately.
- This way, if a different band with different setting is loaded,
- the echoed parts will all get reset appropriately.
- */
- {
- DMUS_MIDI_PMSG *pMidi = (DMUS_MIDI_PMSG *) pMsg;
- if (pMidi->dwPChannel == 7)
- {
- DWORD dwX;
- for (dwX = 0;dwX < 3; dwX++)
- {
- DMUS_MIDI_PMSG * pEcho;
- if (SUCCEEDED(m_pPerformance->AllocPMsg( sizeof(DMUS_MIDI_PMSG),
- (DMUS_PMSG**) &pEcho)))
- {
- static DWORD dwChannels[3] = { 6, 15, 0 };
- static BYTE bPans[3] = { 80,0,120 };
- memcpy( pEcho, pMidi, sizeof(DMUS_MIDI_PMSG) );
- pEcho->dwPChannel = dwChannels[dwX];
- pEcho->mtTime = pMsg->mtTime + 20;
- pEcho->dwFlags = DMUS_PMSGF_MUSICTIME;
- if (pMidi->bStatus == 0xB0)
- {
- if (pMidi->bByte1 == 10)
- {
- pEcho->bByte2 = bPans[dwX];
- }
- else if (pMidi->bByte1 == 7)
- {
- pEcho->bByte2 = pMidi->bByte2 - (((BYTE)dwX+1) * 20);
- if (pEcho->bByte2 > 127) pEcho->bByte2 = 10;
- }
- }
- if (pEcho->pGraph) pEcho->pGraph->AddRef();
- if (pEcho->pTool) pEcho->pTool->AddRef();
- m_pPerformance->SendPMsg( (DMUS_PMSG*)pEcho) ;
- }
- }
- }
- }
- break;
- case DMUS_PMSGT_PATCH:
- break;
- default:
- break;
- }
-
- return hr;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::Flush( IDirectMusicPerformance* pPerf,
- DMUS_PMSG* pMsg, REFERENCE_TIME rt )
- {
- return S_OK;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::Init( IDirectMusicGraph* pGraph )
- {
- return E_NOTIMPL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::GetMsgDeliveryType( DWORD* pdwDeliveryType )
- {
- return E_NOTIMPL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::GetMediaTypeArraySize( DWORD* pdwNumElements )
- {
- return E_NOTIMPL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT STDMETHODCALLTYPE CTool::GetMediaTypes( DWORD** padwMediaTypes,
- DWORD dwNumElements )
- {
- return E_NOTIMPL;
- }
-
-
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- HRESULT BoidMusic::LoadMusic( HWND hwnd )
- {
- HRESULT hr;
-
- CoInitialize(NULL);
- hr = CoCreateInstance( CLSID_DirectMusicLoader, NULL, CLSCTX_INPROC,
- IID_IDirectMusicLoader, (VOID**)&m_pLoader );
- if( FAILED(hr) )
- {
- OutputDebugString("Couldn't create CLSID_DirectMusicLoader\n");
- return hr;
- }
-
- WCHAR dir[MAX_PATH];
-
- m_pLoader->EnableCache(GUID_DirectMusicAllTypes, TRUE);
-
- hr = E_FAIL;
- if (BoidMusic::GetSearchPath(dir))
- {
- hr = m_pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, dir, FALSE);
- }
- if (FAILED(hr))
- {
- hr = m_pLoader->SetSearchDirectory(GUID_DirectMusicAllTypes, L".", FALSE);
- }
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't set DirectMusic search path");
- return hr;
- }
-
- hr = ::CoCreateInstance( CLSID_DirectMusicComposer, NULL, CLSCTX_INPROC,
- IID_IDirectMusicComposer, (VOID**)&m_pComposer);
- if( FAILED(hr) )
- {
- OutputDebugString("Couldn't create CLSID_DirectMusicComposer\n");
- return hr;
- }
-
- BOOL bResourcesOk = TRUE;
-
- bResourcesOk = bResourcesOk && SUCCEEDED( LoadDLS() );
- bResourcesOk = bResourcesOk && LoadStyle();
- bResourcesOk = bResourcesOk && LoadChordMap();
- bResourcesOk = bResourcesOk && LoadTemplate(0,L"BoidsAA.tpl");
- bResourcesOk = bResourcesOk && LoadTemplate(1,L"BoidB1.tpl");
- bResourcesOk = bResourcesOk && LoadTemplate(2,L"BoidsC1.tpl");
- bResourcesOk = bResourcesOk && LoadTemplate(3,L"BoidsCA.tpl");
- bResourcesOk = bResourcesOk && LoadTemplate(4,L"BoidsCB.tpl");
-
- bResourcesOk = bResourcesOk && LoadTemplate(5,L"BoidsCC.tpl");
-
- ComposeSegment(0);
- ComposeSegment(1);
- ComposeSegment(2);
- ComposeSegment(3);
- ComposeSegment(4);
- ComposeSegment(5);
-
- bResourcesOk = bResourcesOk && LoadSegment();
- bResourcesOk = bResourcesOk && GetMotif(0, L"planet");
- bResourcesOk = bResourcesOk && GetMotif(1, L"D motif");
- bResourcesOk = bResourcesOk && GetMotif(2, L"motif RL med");
- bResourcesOk = bResourcesOk && GetMotif(3, L"Cycle");
- bResourcesOk = bResourcesOk && GetMotif(4, L"Expand");
- bResourcesOk = bResourcesOk && GetMotif(5, L"Collapse");
-
- if (!bResourcesOk)
- {
- OutputDebugString("Couldn't load DirectMusic resources\n");
- return E_FAIL;
- }
-
- hr = CoCreateInstance( CLSID_DirectMusic, NULL, CLSCTX_INPROC_SERVER,
- IID_IDirectMusic, (VOID**)&m_pDMusic);
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't create CLSID_DirectMusic\n");
- return hr;
- }
-
- hr = m_pDMusic->SetDirectSound(NULL, hwnd);
- if (FAILED(hr))
- {
- OutputDebugString("Could't SetDirectSound on IDirectMusic\n");
- return hr;
- }
-
- DMUS_PORTPARAMS dmos;
- DMUS_PORTCAPS dmpc;
- GUID guidSynthGUID;
-
- hr = m_pDMusic->GetDefaultPort(&guidSynthGUID);
- if (FAILED(hr))
- {
- OutputDebugString("Could't GetDefaultPort on IDirectMusic\n");
- return hr;
- }
-
- ZeroMemory(&dmos, sizeof(dmos));
- dmos.dwSize = sizeof(DMUS_PORTPARAMS);
- dmos.dwChannelGroups = 1;
- dmos.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS;
-
- hr = m_pDMusic->CreatePort( guidSynthGUID, &dmos, &m_pPort, NULL );
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't CreatePort on IDirectMusic\n");
- return hr;
- }
-
- ZeroMemory(&dmpc, sizeof(dmpc));
- dmpc.dwSize = sizeof(DMUS_PORTCAPS);
-
- hr = m_pPort->GetCaps(&dmpc);
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't GetCaps on IDirectMusicPort\n");
- return hr;
- }
-
- if ((dmpc.dwClass != DMUS_PC_OUTPUTCLASS) || !(dmpc.dwFlags & DMUS_PC_DLS))
- {
- m_pPort->Release();
- m_pPort = NULL;
- }
-
- if (!m_pPort)
- {
- hr = E_FAIL;
-
- for (DWORD index = 0; ; index++)
- {
- ZeroMemory(&dmpc, sizeof(dmpc));
- dmpc.dwSize = sizeof(DMUS_PORTCAPS);
-
- hr = m_pDMusic->EnumPort(index, &dmpc);
- if(SUCCEEDED(hr) && hr != S_FALSE)
- {
- if ( (dmpc.dwClass == DMUS_PC_OUTPUTCLASS) &&
- (dmpc.dwFlags & DMUS_PC_DLS) )
- {
- CopyMemory(&guidSynthGUID, &dmpc.guidPort, sizeof(GUID));
-
- ZeroMemory(&dmos, sizeof(dmos));
- dmos.dwSize = sizeof(DMUS_PORTPARAMS);
- dmos.dwChannelGroups = 1;
- dmos.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS;
-
- hr = m_pDMusic->CreatePort( guidSynthGUID, &dmos,
- &m_pPort, NULL );
- break;
- }
- }
- else
- {
- break;
- }
- }
- }
-
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't find or CreatePort software synthesizer\n");
- return hr;
- }
-
- hr = CoCreateInstance( CLSID_DirectMusicPerformance, NULL, CLSCTX_ALL,
- IID_IDirectMusicPerformance, (VOID**)&m_pPerformance );
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't create CLSID_DirectMusicPerformance\n");
- return hr;
- }
-
- hr = m_pPerformance->Init(&m_pDMusic, NULL, NULL);
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't init CLSID_DirectMusicPerformance\n");
- return hr;
- }
-
- m_pPerformance->AddPort(m_pPort );
- m_pPerformance->AssignPChannelBlock(0, m_pPort, 1);
- m_hNotify = CreateEvent( NULL, FALSE, FALSE, NULL );
- if( m_hNotify )
- {
- GUID guid;
- m_pPerformance->SetNotificationHandle( m_hNotify, 0 );
- guid = GUID_NOTIFICATION_MEASUREANDBEAT;
- m_pPerformance->AddNotificationType( guid );
- }
- m_Tool.m_pPerformance = m_pPerformance;
- if (m_pBand)
- {
- m_pBand->Download(m_pPerformance);
- }
-
- hr = ::CoCreateInstance( CLSID_DirectMusicGraph, NULL, CLSCTX_INPROC,
- IID_IDirectMusicGraph, (VOID**)&m_pGraph );
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't create CLSID_DirectMusicGraph\n");
- return hr;
- }
-
- m_pPerformance->SetGraph(m_pGraph);
- IDirectMusicTool *pTool;
- hr = m_Tool.QueryInterface(IID_IDirectMusicTool, (void**)&pTool);
- if (FAILED(hr))
- {
- OutputDebugString("Couldn't InsertTool on graph\n");
- return hr;
- }
-
- m_pGraph->InsertTool( pTool, 0, NULL, 0);
-
- return S_OK;;
- }
-
-
- //-----------------------------------------------------------------------------
- // Name:
- // Desc:
- //-----------------------------------------------------------------------------
- void BoidMusic::Activate( BOOL bActive )
- {
- if (m_pDMusic)
- {
- m_pDMusic->Activate(bActive);
- }
- }
-